using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace pascal2cs
{
    class Item
    {
        public int Start { get; set; }
        public int End { get; set; }
        public string Text { get; set; }
        public List<Item> children { get; set; }
    }

    public enum SectionType:int{UNIT,INTERFACE,IMPLEMENTATION,INITIALIZATION,FINALIZATION, NONE };
    class section
    {
        public SectionType type{get;set;}
        public int Start { get; set; }
        public int End { get; set; }
        public string CodeText { get; set; }
    }
    public enum InterfaceSectionType:int {
        USES, TYPE, VAR,CONST, NONE
    }

    public enum ImplementationSectionType : int
    {
        USES, TYPE, VAR, CONST, FUNCTION, PROCEDURE,NONE
    }
    public enum TypeFace : int
    {
        ENUM,STRUCT,OBJECT,UNION,CLASS,NONE
    }
    class InterfaceSection
    {
        public InterfaceSectionType type { get; set; }
        public int Start { get; set; }
        public int End { get; set; }
        public string CodeText { get; set; }
    }

    class Freepascal2cppConverter
    {
  
        public static void ConvertFolder(string fromFolder,string toFoloder)
        {
            DirectoryInfo selDir = new DirectoryInfo(fromFolder);
            Directory.CreateDirectory(toFoloder);

            string[] extensions = { "*.pas", "*.inc" };

            List<string> files = new List<string>();
            files.AddRange(Directory.GetFiles(selDir.FullName, "*.pas", SearchOption.AllDirectories));
            files.AddRange(Directory.GetFiles(selDir.FullName, "*.inc", SearchOption.AllDirectories));

            foreach (string file in files)
            {
                FileInfo info = new FileInfo(file);

                string destFolder = toFoloder + "\\" + info.DirectoryName.Replace(fromFolder, "");
                if (!Directory.Exists(destFolder))
                {
                    Directory.CreateDirectory(info.DirectoryName);
                }

                ConvertPasFile(file, destFolder);
            }
        }
        public static void ConvertPasFile(string fromFile,string toFolder)
        {
            Console.WriteLine(string.Format("开始转换文件{0}...",fromFile));
            string textCode = File.ReadAllText(fromFile);
            textCode = removeCommment(textCode);
            StringBuilder cppHeaderCode = new StringBuilder();
            cppHeaderCode.AppendLine("#pragma once");
            cppHeaderCode.AppendLine("");

            textCode = extractMicroHeader(textCode);
            if (fromFile.EndsWith(".inc"))
            {
                textCode = "interface\r\nconst\r\n" + textCode;
            }

            string[] codeLine = textCode.Split("\r\n".ToCharArray());

          

            StringBuilder[] sectionBuilder = new StringBuilder[5] { new StringBuilder(), new StringBuilder(), new StringBuilder(), new StringBuilder(), new StringBuilder() };

            ExtractSection(codeLine, sectionBuilder);

            StringBuilder[] interfaceSectionBuilder = new StringBuilder[4] { new StringBuilder(), new StringBuilder(), new StringBuilder(), new StringBuilder() };
            StringBuilder[] implementationSectionBuilder = new StringBuilder[6] { new StringBuilder(), new StringBuilder(), new StringBuilder(), new StringBuilder(), new StringBuilder(), new StringBuilder() };

            ExtractInerfaceSection(sectionBuilder[(int)SectionType.INTERFACE].ToString().Split(new char[] { '\n', '\r' }), interfaceSectionBuilder);
            ExtractImplementationSection(sectionBuilder[(int)SectionType.IMPLEMENTATION].ToString().Split(new char[] { '\n', '\r' }), implementationSectionBuilder);

            interfaceSectionBuilder[(int)InterfaceSectionType.CONST].AppendLine(implementationSectionBuilder[(int)ImplementationSectionType.CONST].ToString());
            interfaceSectionBuilder[(int)InterfaceSectionType.USES].AppendLine(implementationSectionBuilder[(int)ImplementationSectionType.USES].ToString());
            interfaceSectionBuilder[(int)InterfaceSectionType.TYPE].AppendLine(implementationSectionBuilder[(int)ImplementationSectionType.TYPE].ToString());
            interfaceSectionBuilder[(int)InterfaceSectionType.VAR].AppendLine(implementationSectionBuilder[(int)ImplementationSectionType.VAR].ToString());

            //USES, TYPE, VAR,CONST
            foreach (string line in interfaceSectionBuilder[(int)InterfaceSectionType.USES].ToString().Split(new char[] { '\n', '\r', ',', ';' }))
            {
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                if(line.Trim().StartsWith("#"))
                {
                    cppHeaderCode.AppendLine(line);
                    continue;
                }
                cppHeaderCode.AppendLine("#include \"" + line.Trim() + ".h\"");
            }
            cppHeaderCode.AppendLine();

            foreach (string line in interfaceSectionBuilder[(int)InterfaceSectionType.CONST].ToString().Split(new char[] { '\n', '\r' }))
            {
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                if (line.Trim().StartsWith("#"))
                {
                    cppHeaderCode.AppendLine(line);
                    continue;
                }
                Match match = Regex.Match(line, @"(\w*?\s*?)=\s*?(.*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    cppHeaderCode.AppendLine("#define\t" + match.Groups[1].Value + "\t" + match.Groups[2].Value.Replace("[", "{").Replace("]", "}").Replace("$", "0x"));
                }

            }
            cppHeaderCode.AppendLine();

            foreach (string line in interfaceSectionBuilder[(int)InterfaceSectionType.VAR].ToString().Split(new char[] { '\n', '\r' }))
            {
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                if (line.Trim().StartsWith("#"))
                {
                    cppHeaderCode.AppendLine(line);
                    continue;
                }
                Match match = Regex.Match(line, @"(\w*?)\s*?:\s*?(\w*?)\s*=\s*?(.*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    cppHeaderCode.AppendLine("const\t" + match.Groups[2].Value + "\t" + match.Groups[1].Value + "\t=\t" + match.Groups[3].Value + ";");
                }
            }

            cppHeaderCode.AppendLine();


            bool isNeadClassEnd = false;
            string className = "";
            TypeFace typeFace = TypeFace.NONE;

            foreach (string line in interfaceSectionBuilder[(int)InterfaceSectionType.TYPE].ToString().Split(new char[] { '\n', '\r' }))
            {
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                if (line.Trim().StartsWith("#"))
                {
                    cppHeaderCode.AppendLine(line);
                    continue;
                }
                Match enumMatch = Regex.Match(line, @"(\w*?)\s*=\s*\(([\n\r\s\w,]*?)\);", RegexOptions.IgnoreCase | RegexOptions.Singleline);
                if (enumMatch.Success)
                {
                    cppHeaderCode.AppendLine("enum " + enumMatch.Groups[1].Value);
                    cppHeaderCode.AppendLine("{");
                    cppHeaderCode.AppendLine(enumMatch.Groups[2].Value);
                    cppHeaderCode.AppendLine("};");
                    cppHeaderCode.AppendLine();
                    continue;
                }

                string uniontext = extractUnionHeader(line, ref typeFace, ref isNeadClassEnd, ref className);
                if (!string.IsNullOrWhiteSpace(uniontext))
                {
                    cppHeaderCode.Append(uniontext);
                    continue;
                }

                string structtext = extractStructHeader(line, ref typeFace, ref isNeadClassEnd, ref className);
                if (!string.IsNullOrWhiteSpace(structtext))
                {
                    cppHeaderCode.Append(structtext);
                    continue;
                }

                string structextext = extractStructExHeader(line, ref typeFace, ref isNeadClassEnd, ref className);
                if (!string.IsNullOrWhiteSpace(structextext))
                {
                    cppHeaderCode.Append(structextext);
                    continue;
                }

                string classtext = extractClassHeader(line, ref typeFace, ref isNeadClassEnd, ref className);
                if (!string.IsNullOrWhiteSpace(classtext))
                {
                    cppHeaderCode.Append(classtext);
                    continue;
                }

                string gloablOperatorFunction = extractGlobalOperatorFunction(line);
                if (!string.IsNullOrWhiteSpace(gloablOperatorFunction))
                {
                    cppHeaderCode.Append(gloablOperatorFunction);
                    continue;
                }

                string globalFunction = extractGlobalFunction(line);
                if (!string.IsNullOrWhiteSpace(globalFunction))
                {
                    cppHeaderCode.Append(globalFunction);
                    continue;
                }

                string globalProcedure = extractGlobalProcedure(line);
                if (!string.IsNullOrWhiteSpace(globalProcedure))
                {
                    cppHeaderCode.Append(globalProcedure);
                    continue;
                }

                Match match = Regex.Match(line, @"(\w*?)\s*=\s*\^\s*(\w*);", RegexOptions.IgnoreCase | RegexOptions.Singleline);
                if (match.Success)
                {
                    cppHeaderCode.AppendLine("typedef \t" + match.Groups[1].Value + "\t*" + match.Groups[2].Value + ";");
                    cppHeaderCode.AppendLine();
                    continue;
                }

            }
            cppHeaderCode.AppendLine();


            FileInfo info = new FileInfo(fromFile);
            string fileName = info.Name;

            if(!Directory.Exists(toFolder))
            {
                Directory.CreateDirectory(toFolder);
            }
            string headerText = Regex.Replace(cppHeaderCode.ToString(), @"\binteger\b", @"int", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            headerText = Regex.Replace(headerText, @"\bboolean\b", @"bool", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            headerText = Regex.Replace(headerText, @"\blongword\b", @"int", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            headerText = Regex.Replace(headerText, @"\blongint\b", @"long", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            headerText = Regex.Replace(headerText, @"\bdword\b", @"int", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            headerText = Regex.Replace(headerText, @"\bExtended\b", @"double", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            headerText = Regex.Replace(headerText, @"\bCardinal\b", @"float", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            headerText = Regex.Replace(headerText, @"\bTrue\b", @"true", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            headerText = Regex.Replace(headerText, @"\bFalse\b", @"false", RegexOptions.IgnoreCase | RegexOptions.Multiline);

            Console.WriteLine(string.Format("正在写入文件：{0}", toFolder + "\\" + fileName.Replace(".pas", "") + ".h"));
            File.WriteAllText(toFolder+"\\"+fileName.Replace(".pas", "") + ".h", headerText);

            StringBuilder cppBodyCode = new StringBuilder();               

            string implementationFunction = implementationSectionBuilder[(int)ImplementationSectionType.FUNCTION].ToString();
            string implementationProcedure = implementationSectionBuilder[(int)ImplementationSectionType.PROCEDURE].ToString();

            cppBodyCode.AppendLine("#include\""+ fileName.Replace(".pas","") + ".h" + "\"");
            string functionCodes = extractImplementationFunction(implementationFunction);
            cppBodyCode.AppendLine(functionCodes);
            string procedureCode = extractImplementationProcedure(implementationProcedure);
            cppBodyCode.AppendLine(procedureCode);

            if (!string.IsNullOrWhiteSpace(cppBodyCode.ToString()) && cppBodyCode.Length>50)
            {
                string file = toFolder  +"\\"+ fileName.Replace(".pas", "") + ".cpp";
                Console.WriteLine(string.Format("正在写入文件：{0}", file));
                File.WriteAllText(file, cppBodyCode.ToString());
                Console.WriteLine(string.Format("完成写入"));
            }
            Console.WriteLine(string.Format("转换结束。"));
        }

        private static string extractImplementationProcedure(string implementationProcedure)
        {
            List<string> procedures = new List<string>();
            StringBuilder scopeBuilder = new StringBuilder();
            foreach (string line in implementationProcedure.Split('\r', '\n'))
            {
                bool isOP = line.Trim().StartsWith("constructor", StringComparison.CurrentCultureIgnoreCase) || line.Trim().StartsWith("destructor", StringComparison.CurrentCultureIgnoreCase);
                bool isFun = line.Trim().StartsWith("procedure", StringComparison.CurrentCultureIgnoreCase);
                if (isOP || isFun)
                {

                    string[] codes = scopeBuilder.ToString().TrimEnd().Split("\r\n".ToCharArray());

                    if (codes.Length > 2)
                    {
                        procedures.Add(scopeBuilder.ToString().TrimEnd());
                        scopeBuilder.Clear();
                    }
                    scopeBuilder.AppendLine(line.Trim().TrimEnd());

                }
                else
                {
                    if (!string.IsNullOrWhiteSpace(line))
                    {
                        scopeBuilder.AppendLine(line);
                    }
                }
            }
            if (!string.IsNullOrWhiteSpace(scopeBuilder.ToString()))
            {
                procedures.Add(scopeBuilder.ToString().TrimEnd());
                scopeBuilder.Clear();
            }
            for (int i = 0; i < procedures.Count; i++)
            {
                if (string.IsNullOrWhiteSpace(procedures[i]))
                {
                    continue;
                }

                procedures[i] = Regex.Replace(procedures[i], @"procedure\b\s*(\w*)\.(\w*)\(([\s\S\w]*?)\)\s*;", (match) =>
                {
                    //if(match.Groups[2].Value.Trim().Equals("ClipLine"))
                    //{

                    //}

                    StringBuilder functionScopeBuilder = new StringBuilder();

                    functionScopeBuilder.Append("void " + match.Groups[1].Value + "::" + match.Groups[2].Value + "(");

                    string[] args = match.Groups[3].Value.Split(";");
                    string argtext = reverseFormatArgument(args);

                    functionScopeBuilder.Append(argtext.TrimEnd(',') + ")");
                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                procedures[i] = Regex.Replace(procedures[i], @"procedure\b\s*(\w*?)\.(\w*?)\s*;", (match) =>
                {
                    StringBuilder functionScopeBuilder = new StringBuilder();

                    functionScopeBuilder.Append("void " + match.Groups[1].Value + "::" + match.Groups[2].Value + "()");

                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                procedures[i] = Regex.Replace(procedures[i], @"procedure\b\s*(\w*)\(([\s\S\w]*?)\)\s*;", (match) =>
                {
                    StringBuilder functionScopeBuilder = new StringBuilder();
                    functionScopeBuilder.Append("void " + match.Groups[1].Value + "(");

                    string[] args = match.Groups[2].Value.Split(";");
                    string argtext = reverseFormatArgument(args);

                    functionScopeBuilder.Append(argtext.TrimEnd(',') + ")");
                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                procedures[i] = Regex.Replace(procedures[i], @"procedure\b\s*(\w*)\s*;", (match) =>
                {
                    StringBuilder functionScopeBuilder = new StringBuilder();

                    functionScopeBuilder.Append("void " + match.Groups[1].Value + "()");
                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                procedures[i] = Regex.Replace(procedures[i], @"constructor\b\s*(\w*)\.(\w*)\(([\s\S\w]*?)\)\s*;", (match) =>
                {
                    StringBuilder functionScopeBuilder = new StringBuilder();

                    functionScopeBuilder.Append(match.Groups[1].Value + "::" + match.Groups[2].Value + "(");

                    string[] args = match.Groups[3].Value.Split(";");
                    string argtext = reverseFormatArgument(args);

                    functionScopeBuilder.Append(argtext.TrimEnd(',') + ")");
                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                procedures[i] = Regex.Replace(procedures[i], @"constructor\b\s*(\w*?)\.(\w*?)\s*;", (match) =>
                {
                    StringBuilder functionScopeBuilder = new StringBuilder();

                    functionScopeBuilder.Append(match.Groups[1].Value + "::" + match.Groups[2].Value + "()");

                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                procedures[i] = Regex.Replace(procedures[i], @"destructor\b\s*(\w*)\.(\w*)\(([\s\S\w]*?)\)\s*;", (match) =>
                {
                    StringBuilder functionScopeBuilder = new StringBuilder();

                    functionScopeBuilder.Append(match.Groups[1].Value + "::~" + match.Groups[2].Value + "(");

                    string[] args = match.Groups[3].Value.Split(";");
                    string argtext = reverseFormatArgument(args);

                    functionScopeBuilder.Append(argtext.TrimEnd(',') + ")");
                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                procedures[i] = Regex.Replace(procedures[i], @"destructor\b\s*(\w*?)\.(\w*?)\s*;", (match) =>
                {
                    StringBuilder functionScopeBuilder = new StringBuilder();

                    functionScopeBuilder.Append(match.Groups[1].Value + "::~" + match.Groups[2].Value + "()");

                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                procedures[i] =  revolveFunBody(procedures[i]);
            }

            StringBuilder procedureBuilder = new StringBuilder();
            foreach (string fun in procedures)
            {
                procedureBuilder.AppendLine(fun);
            }

            return procedureBuilder.ToString();
        }

        private static string extractImplementationFunction(string implementationFunction)
        {
            StringBuilder scopeBuilder = new StringBuilder();
            List<string> functions  = new List<string>();


            //bool needBody = false;
            foreach (string line in implementationFunction.Split('\r', '\n'))
            {
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                bool isOP = line.Trim().StartsWith("operator", StringComparison.CurrentCultureIgnoreCase);
                bool isFun = line.Trim().StartsWith("function", StringComparison.CurrentCultureIgnoreCase);
                if (isOP || isFun)
                {
                    string[] codes = scopeBuilder.ToString().TrimEnd().Split("\r\n".ToCharArray());

                    if (codes.Length > 2)
                    {
                        functions.Add(scopeBuilder.ToString().TrimEnd());
                        scopeBuilder.Clear();
                    }
                    scopeBuilder.AppendLine(line.Trim().TrimEnd());
                }
                else
                {
                    if (!string.IsNullOrWhiteSpace(line))
                    {
                        scopeBuilder.AppendLine(line.TrimEnd());
                    }
                }
            }

            if (!string.IsNullOrWhiteSpace(scopeBuilder.ToString()))
            {
                functions.Add(scopeBuilder.ToString().TrimEnd());
                scopeBuilder.Clear();
            }

            for (int i = 0; i < functions.Count; i++)
            {
                if (string.IsNullOrWhiteSpace(functions[i]))
                {
                    continue;
                }
                string result = "";
                functions[i] = Regex.Replace(functions[i], @"function\b\s*(\w*)\.(\w*)\(([\s\S\w]*?)\)\s*:\s*(\w*?);", (match) =>
                {
                    StringBuilder functionScopeBuilder = new StringBuilder();
                    result = match.Groups[4].Value + (match.Groups[4].Value.StartsWith("T", StringComparison.InvariantCultureIgnoreCase) ? "*" : "");
                    functionScopeBuilder.Append(result + " " + match.Groups[1].Value + "::" + match.Groups[2].Value + "(");

                    string[] args = match.Groups[3].Value.Split(";");
                    string argtext = reverseFormatArgument(args);

                    functionScopeBuilder.Append(argtext.TrimEnd(',') + ")");
                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                functions[i] = Regex.Replace(functions[i], @"function\b\s*(\w*?)\.(\w*?)\s*:\s*(\w*?);", (match) =>
                {
                    StringBuilder functionScopeBuilder = new StringBuilder();
                    result = match.Groups[3].Value + (match.Groups[3].Value.StartsWith("T") ? "*" : "");
                    functionScopeBuilder.Append(result + " " + match.Groups[1].Value + "::" + match.Groups[2].Value + "()");

                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                functions[i] = Regex.Replace(functions[i], @"function\b\s*(\w*)\(([\s\S\w]*?)\)\s*:\s*(\w*?);", (match) =>
                {
                    StringBuilder functionScopeBuilder = new StringBuilder();
                    result = match.Groups[3].Value + (match.Groups[3].Value.StartsWith("T") ? "*" : "");
                    functionScopeBuilder.Append(result + " " + match.Groups[1].Value + "(");

                    string[] args = match.Groups[2].Value.Split(";");
                    string argtext = reverseFormatArgument(args);

                    functionScopeBuilder.Append(argtext.TrimEnd(',') + ")");
                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                functions[i] = Regex.Replace(functions[i], @"function\b\s*(\w*)\s*:\s*(\w*?);", (match) =>
                {
                    StringBuilder functionScopeBuilder = new StringBuilder();
                    result = match.Groups[2].Value + (match.Groups[2].Value.StartsWith("T") ? "*" : "");
                    functionScopeBuilder.Append(result + " " + match.Groups[1].Value + "()");
                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                functions[i] = Regex.Replace(functions[i], @"operator\b\s*(.*?)\((.*?)\)\s*?(\w*?)\s*?:\s*(\w*?);", (match) =>
                {
                    StringBuilder functionScopeBuilder = new StringBuilder();

                    string opName = "";
                    if (match.Groups[1].Value.Equals(":="))
                    {
                        opName = "=";
                    }
                    else if (match.Groups[1].Value.Equals("="))
                    {
                        opName = "==";
                    }
                    result = match.Groups[4].Value + (match.Groups[4].Value.StartsWith("T", StringComparison.InvariantCultureIgnoreCase) ? "*" : "");
                    functionScopeBuilder.Append(result + " " + "operator " + opName + "(");

                    string[] args = match.Groups[2].Value.Split(";");
                    string argtext = reverseFormatArgument(args);

                    functionScopeBuilder.Append(argtext.TrimEnd(',') + ")");
                    return functionScopeBuilder.ToString();
                }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

                functions[i] = revolveFunBody(functions[i]);
            }
            StringBuilder functionBuilder = new StringBuilder();
            foreach(string fun in functions)
            {
                functionBuilder.AppendLine(fun);
            }

            return functionBuilder.ToString();
        }


        private static string revolveFunBody(string bodyContent)
        {


            bodyContent = Regex.Replace(bodyContent, @"'begin'", "'be_gin'", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"'end'", "'e_nd'", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bbegin\b", "{\r\n", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bend\b", "}\r\n", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"}\r\n;", "}\r\n", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"'be_gin'", @"'begin'", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"'e_nd'", @"'end'", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"case(.*?)of([\w\s\S]*?)\}", (match) =>
            {
                StringBuilder builder = new StringBuilder();
                builder.Append(Regex.Replace(match.Value, @"case(.*?)of", "switch($1)\r\n{", RegexOptions.IgnoreCase | RegexOptions.Multiline));
                builder.Append(Regex.Replace(match.Value, @"([#\.\w]+?):", "case $1:", RegexOptions.IgnoreCase | RegexOptions.Multiline));
                return builder.ToString();

            }, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bif\b(.*?)\bthen\b", @"if($1)", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\belse\b", @"else", RegexOptions.IgnoreCase | RegexOptions.Multiline);

            bodyContent = Regex.Replace(bodyContent, @"\bfor\b(.*?)\bto\b(.*?)\bdo\b", (match) =>
            {
                StringBuilder builder = new StringBuilder();

                string temp = match.Groups[1].Value.Substring(0, match.Groups[1].Value.IndexOf(':'));
                builder.Append("for(" + match.Groups[1].Value + ";" + temp + "<" + match.Groups[2].Value + ";" + temp + "++)");
                return builder.ToString();

            }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

            bodyContent = Regex.Replace(bodyContent, @"\bwhile\b(.*?)\bdo\b",(match)=> {
                return "while(" + match.Groups[1].Value.Trim() + ")";
            }, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"repeat",(match)=> {
                return "do\r\n{";
            }, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\buntil\b(.*?);", "}\r\nwhile($1)", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\binc\b\((.*?),(.*?)\)", @"$1+=$2", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\binc\b\((.*?)\)", @"$1++", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bdec\b\((.*?),(.*?)\)", @"$1-=$2", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bdec\b\((.*?)\)", @"$1--", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bAssigned\b\((.*?)\)", @"$1!=nullptr", RegexOptions.IgnoreCase | RegexOptions.Multiline);

            bodyContent = Regex.Replace(bodyContent, @":=", @"'`'", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @" = ", @"==", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"'`'", @"=", RegexOptions.IgnoreCase | RegexOptions.Multiline);

            bodyContent = Regex.Replace(bodyContent, @"@", @"&", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bself\b", @"this", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"exit", @"return", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"<>", @"!=", RegexOptions.IgnoreCase | RegexOptions.Multiline);

            bodyContent = Regex.Replace(bodyContent, @"(.*?):(.*?);", @"  $2 $1;", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            //bodyContent = Regex.Replace(bodyContent, @"(.*?):(.*?);", @"$2 $1;", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bord\b\(.*?\)", @"unsined char($1)", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\chr\b\(.*?\)", @"char($1)", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\$([1-9A-Fa-f]{2,})", @"0x$1", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\binteger\b", @"int", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"(\w+)\^", @"&$1", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bboolean\b", @"bool", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bVariant\b|\bpointer\b", @"void*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\band\b", @"&&", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bor\b", @"||", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bnot\b", @"!", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\binherited\b", @"", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"====", @"==", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"\bnil\b","nullptr", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            bodyContent = Regex.Replace(bodyContent, @"'(.*?)'", (match) =>
            {

                if (match.Groups[1].Length == 1)
                {
                    return "'" + match.Groups[1].Value + "'";
                }
                return "\"" + match.Groups[1].Value + "\"";
            }, RegexOptions.IgnoreCase | RegexOptions.Multiline);


            bodyContent = Regex.Replace(bodyContent, @"var\r\n([\s\S\w]*?)\{", (match) =>
            {
                StringBuilder functionScopeBuilder = new StringBuilder();
                functionScopeBuilder.AppendLine("{");

                functionScopeBuilder.AppendLine(match.Groups[1].Value);
                return functionScopeBuilder.ToString();
            }, RegexOptions.IgnoreCase | RegexOptions.Multiline);

            bodyContent = Regex.Replace(bodyContent, @"const\r\n([\s\S\w]*?)\{", (match) =>
            {
                StringBuilder functionScopeBuilder = new StringBuilder();
                functionScopeBuilder.AppendLine("{");

                functionScopeBuilder.AppendLine(match.Groups[1].Value);
                return functionScopeBuilder.ToString();
            }, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            return bodyContent;
        }


        private static string extractGlobalProcedure(string line)
        {
            StringBuilder codeBuilder = new StringBuilder();

            if (line.Trim().StartsWith("procedure", StringComparison.InvariantCultureIgnoreCase))
            {
                Match procedureMatch1 = Regex.Match(line, @"procedure\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (procedureMatch1.Success)
                {
                    codeBuilder.AppendLine(((line.IndexOf("virtual", StringComparison.InvariantCultureIgnoreCase) > 0) ? "virtual " : "") + "void " + procedureMatch1.Groups[1].Value + "();");
                    return codeBuilder.ToString();
                }

                Match procedureMatch2 = Regex.Match(line, @"procedure\s*(\w*?)\((.*?)\);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (procedureMatch2.Success)
                {
                    codeBuilder.Append(((line.IndexOf("virtual", StringComparison.InvariantCultureIgnoreCase) > 0) ? "virtual " : "") + "void " + procedureMatch2.Groups[1].Value + "(");

                    string[] args = procedureMatch2.Groups[2].Value.Split(";");
                    string argtext = reverseFormatArgument(args);
                    codeBuilder.Append(argtext.TrimEnd(',') + ");");
                    codeBuilder.AppendLine();
                    return codeBuilder.ToString();
                }
            }
            return codeBuilder.ToString();
        }

        private static string reverseFormatArgument(string[] args)
        {
            string argtext = "";
            foreach (string arg in args)
            {
                Match argMatch = Regex.Match(arg, @"(const|var|out)\s*(.*?):\s*(\w*)", RegexOptions.Singleline | RegexOptions.IgnoreCase);//|\s*
                if (argMatch.Success)
                {
                    string pre = "";
                    if (!string.IsNullOrWhiteSpace(argMatch.Groups[1].Value))
                    {
                        pre = argMatch.Groups[1].Value.Trim()+" ";
                    }
                    string resultType = argMatch.Groups[3].Value;
                    string [] sa =  argMatch.Groups[2].Value.Split(",".ToCharArray());
                    foreach(string s in sa)
                    {
                        argtext += (pre.StartsWith("const", StringComparison.InvariantCultureIgnoreCase) ? "const " : "") + resultType +" " +((pre.StartsWith("var ", StringComparison.InvariantCultureIgnoreCase) || pre.StartsWith("out ", StringComparison.InvariantCultureIgnoreCase)) ? "&" : "" )+ s + ",";
                    }
                    continue;
                }
                Match argMatch2 = Regex.Match(arg, @"(.*?):\s*(\w*)", RegexOptions.Singleline | RegexOptions.IgnoreCase);//|\s*
                if (argMatch2.Success)
                {
                    string resultType = argMatch2.Groups[2].Value;
                    string[] sa = argMatch2.Groups[1].Value.Split(",".ToCharArray());
                    foreach (string s in sa)
                    {
                        argtext +=  resultType + " " +  s + ",";
                    }
                    continue;
                }
            }

            return argtext.TrimEnd(",".ToCharArray()).Replace("\r"," ").Replace("\n"," ");
        }

        private static string extractGlobalFunction(string line)
        {
            StringBuilder codeBuilder = new StringBuilder();
            if (line.Trim().StartsWith("function",StringComparison.InvariantCultureIgnoreCase))
            {
                Match functionMatch1 = Regex.Match(line, @"function\s*(\w*?):\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (functionMatch1.Success)
                {
                    codeBuilder.AppendLine(((line.IndexOf("virtual", StringComparison.InvariantCultureIgnoreCase) > 0) ? "virtual" : "") + functionMatch1.Groups[2].Value + " " + functionMatch1.Groups[1].Value + "();");
                    return codeBuilder.ToString();
                }

                Match functionMatch2 = Regex.Match(line, @"function\s*(\w*?)\s*\((.*?)\):\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (functionMatch2.Success)
                {
                    codeBuilder.Append(((line.IndexOf("virtual", StringComparison.InvariantCultureIgnoreCase) > 0) ? "virtual " : "") + "  " + functionMatch2.Groups[3].Value + (functionMatch2.Groups[3].Value.StartsWith("T") ? "*" : "") + " " + functionMatch2.Groups[1].Value + "(");

                    string[] args = functionMatch2.Groups[2].Value.Split(";");
                    string argtext = reverseFormatArgument(args);
                    codeBuilder.Append(argtext.TrimEnd(',') + ");");
                    codeBuilder.AppendLine();
                    return codeBuilder.ToString();
                }
                
            }
            return codeBuilder.ToString();
        }

        private static string extractGlobalOperatorFunction(string line)
        {
            StringBuilder codeBuilder = new StringBuilder();

            if (line.Trim().StartsWith("operator", StringComparison.InvariantCultureIgnoreCase))
            {
                Match opmatch = Regex.Match(line, @"operator\s*(.*?)\s*\((.*?)\).*:\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (opmatch.Success)
                {
                    codeBuilder.Append(opmatch.Groups[3].Value + "  operator " + opmatch.Groups[1].Value.Trim(':') + "(");

                    string[] args = opmatch.Groups[2].Value.Split(";");
                    string argtext = reverseFormatArgument(args);
                    codeBuilder.Append(argtext.TrimEnd(',') + ");");
                    codeBuilder.AppendLine();
                    return codeBuilder.ToString();
                }
            }
            return codeBuilder.ToString();
        }

        private static string removeCommment(string interfaceSectionString)
        {
             interfaceSectionString = Regex.Replace(interfaceSectionString, @"\{\w[\s\S\w]*?\}", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            interfaceSectionString = Regex.Replace(interfaceSectionString, @"\{[^$][\s\S\w]*?\}", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            interfaceSectionString = Regex.Replace(interfaceSectionString, @"\{\s[\s\S\w]*?\s\}", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            interfaceSectionString = Regex.Replace(interfaceSectionString, @"\s*\/\/.*", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            interfaceSectionString = Regex.Replace(interfaceSectionString, @"\w*?\s*=\s*?.*?record[\n|\r\s]*?case[\s\w]*?of", (match) => { return match.Value.Replace('\n', ' ').Replace('\r', ' '); }, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            return interfaceSectionString;
        }

        private static String extractStructHeader(string line, ref TypeFace typeFace, ref bool isNeadClassEnd, ref string className)
        {
            if (typeFace != TypeFace.NONE && typeFace != TypeFace.STRUCT)
            {
                return string.Empty;
            }
            StringBuilder codeBuilder = new StringBuilder();
            if (isNeadClassEnd)
            {
                if (line.Trim().ToLower() == "end;")
                {
                    isNeadClassEnd = false;
                    typeFace = TypeFace.NONE;
                    className = "";
                    codeBuilder.AppendLine("};");
                    codeBuilder.AppendLine();

                    return codeBuilder.ToString();
                }
 

                Match memberMatch = Regex.Match(line, @"(\w*?)\s*:\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (memberMatch.Success)
                {
                    string memberType = memberMatch.Groups[2].Value;

                    codeBuilder.AppendLine("  " + memberType + (memberType.StartsWith("T",StringComparison.InvariantCultureIgnoreCase) ? "*" : "") + "\t" + memberMatch.Groups[1].Value + ";");
                }
            }

            Match classMatch3 = Regex.Match(line, @"(\w*?)\s*=\s*?.*?record", RegexOptions.Singleline | RegexOptions.IgnoreCase);

            if (classMatch3.Success)
            {
                isNeadClassEnd = true;
                typeFace = TypeFace.STRUCT;
                className = classMatch3.Groups[1].Value.Trim();
                codeBuilder.AppendLine();
                codeBuilder.AppendLine("struct " + classMatch3.Groups[1].Value.Trim() + "{");
                return codeBuilder.ToString();
            }
            return codeBuilder.ToString();
        }

        private static String extractUnionHeader(string line, ref TypeFace typeFace, ref bool isNeadClassEnd, ref string className)
        {
            if (typeFace != TypeFace.NONE && typeFace != TypeFace.UNION)
            {
                return string.Empty;
            }
            StringBuilder codeBuilder = new StringBuilder();
            if (isNeadClassEnd)
            {
                if (line.Trim().ToLower() == "end;")
                {
                    isNeadClassEnd = false;
                    typeFace = TypeFace.NONE;
                    className = "";
                    codeBuilder.AppendLine("};");
                    codeBuilder.AppendLine();

                    return codeBuilder.ToString();
                }


                Match memberMatch = Regex.Match(line, @"\((\w*?)\s*:\s*(\w*?)\);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (memberMatch.Success)
                {
                    string memberType = memberMatch.Groups[2].Value;

                    codeBuilder.AppendLine("  " + memberType + "\t" + memberMatch.Groups[1].Value + ";");
                }
            }

            Match classMatch3 = Regex.Match(line, @"(\w*?)\s*=\s*?.*?record\s*?case[\s\w]*?of", RegexOptions.Singleline | RegexOptions.IgnoreCase);
            //
            if (classMatch3.Success)
            {
                isNeadClassEnd = true;
                typeFace = TypeFace.UNION;
                className = classMatch3.Groups[1].Value.Trim();
                codeBuilder.AppendLine();
                codeBuilder.AppendLine("union " + classMatch3.Groups[1].Value.Trim() + "{");
                return codeBuilder.ToString();
            }
            return codeBuilder.ToString();
        }

        private static String extractStructExHeader(string line, ref TypeFace typeFace, ref bool isNeadClassEnd, ref string className)
        {
            if (typeFace != TypeFace.NONE && typeFace != TypeFace.OBJECT)
            {
                return string.Empty;
            }
            StringBuilder codeBuilder = new StringBuilder();
            if (isNeadClassEnd)
            {
                if (line.Trim().ToLower() == "end;")
                {
                    isNeadClassEnd = false;
                    typeFace = TypeFace.NONE;
                    className = "";
                    codeBuilder.AppendLine("};");
                    codeBuilder.AppendLine();

                    return codeBuilder.ToString();
                }
                if (line.Trim().StartsWith("function", StringComparison.InvariantCultureIgnoreCase))
                {
                    Match functionMatch1 = Regex.Match(line, @"function\s*(\w*?):\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    if (functionMatch1.Success)
                    {
                        codeBuilder.AppendLine(((line.IndexOf("virtual") > 0) ? "  virtual" : "") + "  " + functionMatch1.Groups[2].Value + " " + functionMatch1.Groups[1].Value + "();");
                        return codeBuilder.ToString();
                    }

                    Match functionMatch2 = Regex.Match(line, @"function\s*(\w*?)\s*\((.*?)\):\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    if (functionMatch2.Success)
                    {
                        codeBuilder.Append(((line.IndexOf("virtual") > 0) ? "  virtual" : "") + "  " + functionMatch2.Groups[3].Value + (functionMatch2.Groups[3].Value.StartsWith("T") ? "*" : "") + " " + functionMatch2.Groups[1].Value + "(");

                        string[] args = functionMatch2.Groups[2].Value.Split(";");
                        string argtext = reverseFormatArgument(args);
                        codeBuilder.Append(argtext.TrimEnd(',') + ");");
                        codeBuilder.AppendLine();
                        return codeBuilder.ToString();
                    }
                    return codeBuilder.ToString();
                }

                if (line.Trim().StartsWith("procedure", StringComparison.InvariantCultureIgnoreCase))
                {
                    Match procedureMatch1 = Regex.Match(line, @"procedure\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    if (procedureMatch1.Success)
                    {
                        codeBuilder.AppendLine(((line.IndexOf("virtual") > 0) ? "  virtual" : "") + "  void " + procedureMatch1.Groups[1].Value + "();");
                        return codeBuilder.ToString();
                    }

                    Match procedureMatch2 = Regex.Match(line, @"procedure\s*(\w*?)\((.*?)\);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    if (procedureMatch2.Success)
                    {
                        codeBuilder.Append(((line.IndexOf("virtual") > 0) ? "  virtual" : "") + "  void " + procedureMatch2.Groups[1].Value + "(");

                        string[] args = procedureMatch2.Groups[2].Value.Split(";");
                        string argtext = reverseFormatArgument(args);
                        codeBuilder.Append(argtext.TrimEnd(',') + ");");
                        codeBuilder.AppendLine();
                        return codeBuilder.ToString();
                    }
                    return codeBuilder.ToString();

                }



                Match memberMatch = Regex.Match(line, @"(\w*?)\s*:\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (memberMatch.Success)
                {
                    string memberType = memberMatch.Groups[2].Value;

                    codeBuilder.AppendLine("  " + memberType + (memberType.StartsWith("T") ? "*" : "") + "\t" + memberMatch.Groups[1].Value + ";");
                }
            }


            Match classMatch1 = Regex.Match(line, @"(\w*?)\s*=\s*object", RegexOptions.Singleline | RegexOptions.IgnoreCase);
            if (classMatch1.Success)
            {
                isNeadClassEnd = true;
                typeFace = TypeFace.OBJECT;
                className = classMatch1.Groups[1].Value.Trim();
                codeBuilder.AppendLine("struct " + classMatch1.Groups[1].Value.Trim() + "{");
                return codeBuilder.ToString();
            }
            Match classMatch2 = Regex.Match(line, @"(\w*?)\s*=\s*object\((\w*?)\);", RegexOptions.Singleline | RegexOptions.IgnoreCase);

            if (classMatch2.Success)
            {
                isNeadClassEnd = true;
                typeFace = TypeFace.OBJECT;
                className = classMatch2.Groups[1].Value.Trim();
                codeBuilder.AppendLine("struct " + classMatch2.Groups[1].Value.Trim() + " : public " + classMatch2.Groups[2].Value.Trim() + "{};");
                return codeBuilder.ToString();
            }

            Match classMatch3 = Regex.Match(line, @"(?<1>\w*?)\s*=\s*object\((?<2>\w*?)\)|(?<1>\w*?)\s*=\s*?interface\((?<2>.*?)\)", RegexOptions.Singleline | RegexOptions.IgnoreCase);

            if (classMatch3.Success)
            {
                isNeadClassEnd = true;
                typeFace = TypeFace.OBJECT;
                className = classMatch3.Groups[1].Value.Trim();
                codeBuilder.AppendLine();
                codeBuilder.AppendLine("struct " + classMatch3.Groups[1].Value.Trim() + " : public " + classMatch3.Groups[2].Value.Trim() + "{");
                return codeBuilder.ToString();
            }
            return codeBuilder.ToString();
        }

        private static String extractClassHeader(string line, ref TypeFace typeFace, ref bool isNeadClassEnd,ref string className)
        {
            if(typeFace != TypeFace.NONE && typeFace != TypeFace.CLASS)
            {
                return string.Empty;
            }

            StringBuilder codeBuilder = new StringBuilder();
            if (isNeadClassEnd)
            {
                if (line.Trim().ToLower() == "private")
                {
                    codeBuilder.AppendLine("private:");
                    return codeBuilder.ToString();
                }
                if (line.Trim().ToLower() == "protected")
                {
                    codeBuilder.AppendLine("protected:");
                    return codeBuilder.ToString();
                }
                if (line.Trim().ToLower() == "public")
                {
                    codeBuilder.AppendLine("public:");
                    return codeBuilder.ToString();
                }
                if (line.Trim().ToLower() == "end;")
                {
                    isNeadClassEnd = false;
                    typeFace = TypeFace.NONE;
                    className = "";
                    codeBuilder.AppendLine("};");
                    codeBuilder.AppendLine();

                    return codeBuilder.ToString();
                }
                if (line.Trim().StartsWith("function", StringComparison.InvariantCultureIgnoreCase))
                {
                    Match functionMatch1 = Regex.Match(line, @"function\s*(\w*?)\s*:\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    if (functionMatch1.Success)
                    {
                        codeBuilder.AppendLine(((line.IndexOf("virtual") > 0) ? "  virtual" : "") + "  " + functionMatch1.Groups[2].Value + " " + functionMatch1.Groups[1].Value + "();");
                        return codeBuilder.ToString();
                    }

                    Match functionMatch2 = Regex.Match(line, @"function\s*(\w*?)\s*\((.*?)\)\s*:\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    if (functionMatch2.Success)
                    {
                        codeBuilder.Append(((line.IndexOf("virtual", StringComparison.InvariantCultureIgnoreCase) > 0) ? "  virtual" : "") + "  " + functionMatch2.Groups[3].Value + (functionMatch2.Groups[3].Value.StartsWith("T", StringComparison.InvariantCultureIgnoreCase) ? "*" : "") + " " + functionMatch2.Groups[1].Value + "(");

                        string[] args = functionMatch2.Groups[2].Value.Split(";");
                        string argtext = reverseFormatArgument(args);

                        codeBuilder.Append(argtext.TrimEnd(',') + ");");
                        codeBuilder.AppendLine();
                        return codeBuilder.ToString();
                    }

 

                    return codeBuilder.ToString();
                }

                if (line.Trim().StartsWith("procedure", StringComparison.InvariantCultureIgnoreCase))
                {
                    Match procedureMatch1 = Regex.Match(line, @"procedure\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    if (procedureMatch1.Success)
                    {
                        codeBuilder.AppendLine(((line.IndexOf("virtual", StringComparison.InvariantCultureIgnoreCase) > 0) ? "  virtual" : "") + "  void " + procedureMatch1.Groups[1].Value + "();");
                        return codeBuilder.ToString();
                    }

                    Match procedureMatch2 = Regex.Match(line, @"procedure\s*(\w*?)\((.*?)\);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    if (procedureMatch2.Success)
                    {
                        codeBuilder.Append(((line.IndexOf("virtual", StringComparison.InvariantCultureIgnoreCase) > 0) ? "  virtual" : "") + "  void " + procedureMatch2.Groups[1].Value + "(");

                        string[] args = procedureMatch2.Groups[2].Value.Split(";");
                        string argtext = reverseFormatArgument(args);
                        codeBuilder.Append(argtext.TrimEnd(',') + ");");
                        codeBuilder.AppendLine();
                        return codeBuilder.ToString();
                    }
                    return codeBuilder.ToString();

                }

                if (line.Trim().StartsWith("constructor", StringComparison.InvariantCultureIgnoreCase))
                {
                    Match procedureMatch1 = Regex.Match(line, @"constructor\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    if (procedureMatch1.Success)
                    {
                        codeBuilder.AppendLine("  " + className + "();");
                        return codeBuilder.ToString();
                    }

                    Match procedureMatch2 = Regex.Match(line, @"constructor\s*(\w*?)\((.*?)\);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    if (procedureMatch2.Success)
                    {
                        codeBuilder.Append("  " + className + "(");

                        string[] args = procedureMatch2.Groups[2].Value.Split(";");
                        string argtext = reverseFormatArgument(args);
                        codeBuilder.Append(argtext.TrimEnd(',') + ");");
                        codeBuilder.AppendLine();
                        return codeBuilder.ToString();
                    }
                    return codeBuilder.ToString();

                }

                if (line.Trim().StartsWith("destructor", StringComparison.InvariantCultureIgnoreCase))
                {
                    Match procedureMatch1 = Regex.Match(line, @"destructor\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                    if (procedureMatch1.Success)
                    {
                        codeBuilder.AppendLine("  virtual ~" + className + "();");
                        return codeBuilder.ToString();
                    }
                    return codeBuilder.ToString();

                }



                Match memberMatch = Regex.Match(line, @"(\w*?)\s*:\s*(\w*?);", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                if (memberMatch.Success)
                {
                    string memberType = memberMatch.Groups[2].Value;

                    codeBuilder.AppendLine("  " + memberType + (memberType.StartsWith("T") ? "*" : "") + "\t" + memberMatch.Groups[1].Value + ";");
                }
            }


            Match classMatch1 = Regex.Match(line, @"(\w*?)\s*=\s*class;", RegexOptions.Singleline | RegexOptions.IgnoreCase);
            if (classMatch1.Success)
            {
                codeBuilder.AppendLine("class " + classMatch1.Groups[1].Value.Trim() + ";");
                return codeBuilder.ToString();
            }
            Match classMatch2 = Regex.Match(line, @"(\w*?)\s*=\s*class\((\w*?)\);", RegexOptions.Singleline | RegexOptions.IgnoreCase);

            if (classMatch2.Success)
            {
                codeBuilder.AppendLine("class " + classMatch2.Groups[1].Value.Trim() + " : public " + classMatch2.Groups[2].Value.Trim() + "{};");
                return codeBuilder.ToString();
            }

            Match classMatch3 = Regex.Match(line, @"(\w*?)\s*=\s*class\((\w*?)\)", RegexOptions.Singleline | RegexOptions.IgnoreCase);

            if (classMatch3.Success)
            {
                isNeadClassEnd = true;
                typeFace = TypeFace.CLASS;
                className = classMatch3.Groups[1].Value.Trim();
                codeBuilder.AppendLine();
                codeBuilder.AppendLine("class " + classMatch3.Groups[1].Value.Trim() + " : public " + classMatch3.Groups[2].Value.Trim() + "{");
                return codeBuilder.ToString();
            }
            return codeBuilder.ToString();
        }

        private static string extractMicroHeader(string line)
        {

            line = Regex.Replace(line, @"\{\$IFDEF(.*?)\}", @"#ifdef  $1", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            line = Regex.Replace(line, @"\{\$UNDEF(.*?)\}", @"#undef  $1", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            line = Regex.Replace(line, @"\{\$IF\s*?(.*?)\}", @"#if $1", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            line = Regex.Replace(line, @"\{\$I\b\s*(.*?)\s*?\}", "#include \"$1.h\"", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            line = Regex.Replace(line, @"\{\$ENDIF\s*\}", @"#endif ", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            line = Regex.Replace(line, @"\{\$else\s*\}", @"#else ", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            line = Regex.Replace(line, @"\{\$define(.*?)\}", @"#define $1", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            line = Regex.Replace(line, @"\{\$(.*?)\}", @"", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            return line.Trim();
        }

        private static void ExtractInerfaceSection(string[] codes, StringBuilder[] interfaceSectionBuilder)
        {
            InterfaceSectionType interfaceSectionType = InterfaceSectionType.NONE;
            foreach (string line in codes)
            {
                if(string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }
                if (line.Equals("uses", StringComparison.CurrentCultureIgnoreCase))//USES, TYPE, VAR,CONST
                {
                    interfaceSectionType = InterfaceSectionType.USES;
                    continue;
                }
                else if (line.Equals("type", StringComparison.CurrentCultureIgnoreCase))
                {
                    interfaceSectionType = InterfaceSectionType.TYPE;
                    continue;
                }
                else if (line.Equals("var", StringComparison.CurrentCultureIgnoreCase))
                {
                    interfaceSectionType = InterfaceSectionType.VAR;
                    continue;
                }
                else if (line.Equals("const", StringComparison.CurrentCultureIgnoreCase))
                {
                    interfaceSectionType = InterfaceSectionType.CONST;
                    continue;
                }

                if (interfaceSectionType == InterfaceSectionType.USES)
                {
                    interfaceSectionBuilder[(int)InterfaceSectionType.USES].AppendLine(line);
                }
                else if (interfaceSectionType == InterfaceSectionType.TYPE)
                {
                    interfaceSectionBuilder[(int)InterfaceSectionType.TYPE].AppendLine(line);
                }
                else if (interfaceSectionType == InterfaceSectionType.VAR)
                {
                    interfaceSectionBuilder[(int)InterfaceSectionType.VAR].AppendLine(line);
                }
                else if (interfaceSectionType == InterfaceSectionType.CONST)
                {
                    interfaceSectionBuilder[(int)InterfaceSectionType.CONST].AppendLine(line);
                }
            }
        }

        private static void ExtractImplementationSection(string[] codes, StringBuilder[] implementationSectionBuilder)
        {
            ImplementationSectionType implementationSectionType = ImplementationSectionType.NONE;
            
            foreach (string line in codes)
            {
                bool isFunction = implementationSectionType == ImplementationSectionType.FUNCTION || implementationSectionType == ImplementationSectionType.PROCEDURE;
                if (line.IndexOf("uses", StringComparison.CurrentCultureIgnoreCase)==0)//USES, TYPE, VAR,CONST
                {
                    implementationSectionType = ImplementationSectionType.USES;
                    continue;
                }
                else if (line.IndexOf("type", StringComparison.CurrentCultureIgnoreCase)==0)
                {
                    implementationSectionType = ImplementationSectionType.TYPE;
                    continue;
                }
                else if (!isFunction && line.IndexOf("var", StringComparison.CurrentCultureIgnoreCase)==0)
                {
                    implementationSectionType = ImplementationSectionType.VAR;
                    continue;
                }
                else if (!isFunction &&  line.IndexOf("const", StringComparison.CurrentCultureIgnoreCase) ==0 && !line.StartsWith("constructor", StringComparison.CurrentCultureIgnoreCase))
                {
                    implementationSectionType = ImplementationSectionType.CONST;
                    continue;
                }
                else if (line.IndexOf("function", StringComparison.CurrentCultureIgnoreCase)==0 || line.IndexOf("operator", StringComparison.CurrentCultureIgnoreCase) == 0)
                {
                    implementationSectionBuilder[(int)ImplementationSectionType.FUNCTION].AppendLine(line);
                    implementationSectionType = ImplementationSectionType.FUNCTION;
                    continue;
                }
                else if (line.IndexOf("procedure", StringComparison.CurrentCultureIgnoreCase)==0 || line.IndexOf("destructor", StringComparison.CurrentCultureIgnoreCase) == 0 || line.IndexOf("constructor", StringComparison.CurrentCultureIgnoreCase) == 0)
                {
                    implementationSectionBuilder[(int)ImplementationSectionType.PROCEDURE].AppendLine(line);
                    implementationSectionType = ImplementationSectionType.PROCEDURE;
                    continue;
                }
                

                if (implementationSectionType == ImplementationSectionType.USES)
                {
                    implementationSectionBuilder[(int)ImplementationSectionType.USES].AppendLine(line);
                }
                else if (implementationSectionType == ImplementationSectionType.TYPE)
                {
                    implementationSectionBuilder[(int)ImplementationSectionType.TYPE].AppendLine(line);
                }
                else if (implementationSectionType == ImplementationSectionType.VAR)
                {
                    implementationSectionBuilder[(int)ImplementationSectionType.VAR].AppendLine(line);
                }
                else if (implementationSectionType == ImplementationSectionType.CONST)
                {
                    implementationSectionBuilder[(int)ImplementationSectionType.CONST].AppendLine(line);
                }
                else if (implementationSectionType == ImplementationSectionType.FUNCTION)
                {
                    implementationSectionBuilder[(int)ImplementationSectionType.FUNCTION].AppendLine(line);
                }
                else if (implementationSectionType == ImplementationSectionType.PROCEDURE)
                {
                    implementationSectionBuilder[(int)ImplementationSectionType.PROCEDURE].AppendLine(line);
                }
            }
        }

        private static void ExtractSection(string[] codeLine, StringBuilder [] sectionBuilder)
        {
            SectionType currentSectionType = SectionType.NONE;

            foreach (string code in codeLine)
            {
                if(string.IsNullOrWhiteSpace(code))
                {
                    continue;
                }

                if (!string.IsNullOrWhiteSpace(code) && code.Trim().StartsWith("unit", StringComparison.CurrentCultureIgnoreCase))
                {
                    // unitCodeBuilder.AppendLine(code);
                    currentSectionType = SectionType.UNIT;
                    continue;

                }
                else if (!string.IsNullOrWhiteSpace(code) && code.Trim().StartsWith("interface", StringComparison.CurrentCultureIgnoreCase))
                {
                    //interfaceCodeBuilder.AppendLine(code);
                    currentSectionType = SectionType.INTERFACE;
                    continue;
                }
                else if (!string.IsNullOrWhiteSpace(code) && code.Trim().StartsWith("implementation", StringComparison.CurrentCultureIgnoreCase))
                {
                    //implementationCodeBuilder.AppendLine(code);
                    currentSectionType = SectionType.IMPLEMENTATION;
                    continue;
                }
                else if (!string.IsNullOrWhiteSpace(code) && code.Trim().StartsWith("initialization", StringComparison.CurrentCultureIgnoreCase))
                {
                    //initializationCodeBuilder.AppendLine(code);
                    currentSectionType = SectionType.INITIALIZATION;
                    continue;
                }
                else if (!string.IsNullOrWhiteSpace(code) && code.Trim().StartsWith("finalization", StringComparison.CurrentCultureIgnoreCase))
                {
                    //finalizationCodeBuilder.AppendLine(code);
                    currentSectionType = SectionType.FINALIZATION;
                    continue;
                }
                else if (!string.IsNullOrWhiteSpace(code) && code.Trim().StartsWith("end.", StringComparison.CurrentCultureIgnoreCase))
                {
                    currentSectionType = SectionType.NONE;
                    continue;
                }

                if (currentSectionType == SectionType.UNIT)
                {
                    sectionBuilder[(int)SectionType.INTERFACE].AppendLine("uses");
                    sectionBuilder[(int)SectionType.INTERFACE].AppendLine(code.Trim()); 
                }
                if (currentSectionType == SectionType.INTERFACE)
                {
                    sectionBuilder[(int)SectionType.INTERFACE].AppendLine(code.Trim());
                }
                if (currentSectionType == SectionType.IMPLEMENTATION)
                {
                    sectionBuilder[(int)SectionType.IMPLEMENTATION].AppendLine(code.Trim());
                }
                if (currentSectionType == SectionType.INITIALIZATION)
                {
                    sectionBuilder[(int)SectionType.INITIALIZATION].AppendLine(code.Trim());
                }
                if (currentSectionType == SectionType.FINALIZATION)
                {
                    sectionBuilder[(int)SectionType.FINALIZATION].AppendLine(code.Trim());
                }


            }
        }

     


    }
}
